import './SortBox.scss'
import { useState } from 'react'
import { Button, Radio } from 'antd'
import { CSS } from '@dnd-kit/utilities'
import { useEventEmitter, useMount } from 'ahooks'

import { SortDescendingOutlined, SortAscendingOutlined, CloseCircleOutlined } from '@ant-design/icons'
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'
import { useSortable, arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable'


const SortableItem = ({ id, label, value, SortableEvent, init }) => {
    const [Value, setValue] = useState()
    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id })
    const style = { transform: CSS.Transform.toString(transform), transition }
    const onClick = () => {
        SortableEvent.emit({ [value]: '' })
        setValue('')
    }
    const onChange = (e) => {
        SortableEvent.emit({ [value]: e.target.value })
        setValue(e.target.value)
    }
    useMount(() => {
        if (init[value]) {
            const [data] = init[value].split('@')
            SortableEvent.emit({ [value]: data })
            setValue(data)
        }
    })
    return (
        <div className='SortableItem' ref={setNodeRef} style={style} {...attributes}>
            <div  {...listeners}>{label}</div>
            <div>
                <Radio.Group value={Value} onChange={onChange} buttonStyle="solid">
                    <Radio.Button value="asc" ><SortDescendingOutlined /></Radio.Button>
                    <Radio.Button value="desc" ><SortAscendingOutlined /></Radio.Button>
                </Radio.Group>
                <Button type='link' icon={<CloseCircleOutlined />} danger onClick={onClick}></Button>
            </div>
        </div>
    )
}

const SortBox = ({ data, ModalEvent, Off }) => {
    const { sortCriteria, init, SortData } = data
    const [items, setItems] = useState([])
    const [sort, setSort] = useState(SortData)
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, {
            coordinateGetter: sortableKeyboardCoordinates,
        })
    )
    const handleDragEnd = (event) => {
        const { active, over } = event
        if (active.id !== over.id) {
            setItems((items) => {
                const oldIndex = items.findIndex(v => v.id === active.id)
                const newIndex = items.findIndex(v => v.id === over.id)
                return arrayMove(items, oldIndex, newIndex)
            })
        }
    }
    const SortableEvent = useEventEmitter()
    SortableEvent.useSubscription(val => {
        setSort(e => ({ ...e, ...val }))
    })
    const onSort = () => {
        let sortObj = {}
        Object.keys(sort).forEach(key => {
            if (sort[key]) {
                const numebr = items.findIndex(v => v.value === key)
                sortObj = { ...sortObj, [key]: `${sort[key]}@${numebr}` }
            }
        })
        ModalEvent.emit({ type: 'Sort', data: sortObj })
        Off()
    }
    const onReset = () => {
        initSortArray(init)
        ModalEvent.emit({ type: 'SorRef' })
        Off()
    }
    const initSortArray = (data) => {
        const entries = Object.entries(data).map(([key, value]) => {
            const number = parseInt(value.split('@')[1], 10)
            return { key, number }
        });
        entries.sort((a, b) => a.number - b.number)
        const sortedKeys = entries.map(entry => entry.key)
        sortCriteria.sort((a, b) => {
            const indexA = sortedKeys.indexOf(a.value)
            const indexB = sortedKeys.indexOf(b.value)
            if (indexA !== -1 && indexB !== -1) return indexA - indexB
            else if (indexA !== -1) return -1
            else if (indexB !== -1) return 1
            else return a.id - b.id
        })
        setItems(sortCriteria)
    }
    useMount(() => initSortArray(SortData))
    return (
        <div className='SortBox'>
            <DndContext
                sensors={sensors}
                collisionDetection={closestCenter}
                onDragEnd={handleDragEnd}
                handle
            >
                <SortableContext
                    items={items}
                    strategy={verticalListSortingStrategy}
                >
                    {items.map(({ id, label, value }) => <SortableItem key={id} id={id} label={label} value={value} SortableEvent={SortableEvent} init={sort} />)}
                </SortableContext>
            </DndContext>
            <div className='options'>
                <Button type='primary' size='large' onClick={onSort}>排序</Button>
                <Button size='large' onClick={onReset}>重置</Button>
            </div>
        </div>
    );
};

export default SortBox;